#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
#include<cstdio>
#include<unordered_map>
#include<map>
using namespace std;
typedef long long LL;
const int N = 5e5 + 10;
int p[N];
int p2[N];
int sz[N];
int n, m, k;
map<pair<int, int>, bool>mp;
int find1(int x)
{
	if (x != p[x]) p[x] = find1(p[x]);
	return p[x];
}
int find2(int x)
{
	if (x != p2[x]) p2[x] = find2(p2[x]);
	return p2[x];
}
int main()
{
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= N - 10; i++)p[i] = i;
	while (m--) {
		int a, b;
		scanf("%d%d", &a, &b);
		if (a > n || b > n)continue;
		if (a > b) {
			swap(a, b);
		}
		if (mp[{a, b}])continue;
		mp[{a, b}] = 1;
		int a1 = find1(a);
		int b1 = find1(b);
		if (a1 != b1)p[a1] = b1;
	}
	//cout << "cnt==" << cnt << endl;
	mp.clear();
	/*for (int i = 1; i <= n; i++) {
		cout << "find==" << find1(i) << endl;
	}*/
	int k;
	scanf("%d", &k);
	int cnt = 0;
	for (int i = 1; i <= N-10; i++)p2[i] = i, sz[i] = 1;
	while (k--) {
		int a, b;
		scanf("%d%d", &a, &b);
		if (a > n || b > n)continue;
		if (a > b) {
			swap(a, b);
		}
		if (mp[{a, b}])continue;
		mp[{a, b}] = 1;
		cnt++;
		int a1 = find1(a);
		int b1 = find1(b);
		int a2 = find2(a);
		int b2 = find2(b);
		if (a1 == b1) {
			if (a2 != b2) {
				p2[a2] = b2;
				sz[b2] += sz[a2];
			}
		}
	}
	//cout << "cnt==" << cnt << endl;
	int ma = 1, mi = 1e9;
	for (int i = 1; i <= n; i++) {
		/*if (p2[i] == i) {
			ma = max(ma, sz[i]);
			mi = min(mi, sz[i]);
		}*/
		if (p2[i] == i) {
			//cout << "i==" << i << endl;
			//cout << "sz[i]==" << sz[i] << endl;
			ma = max(ma, sz[i]);
			mi = min(mi, sz[i]);
		}
	}
	cout << ma << " " << mi << endl;
	cout << endl;
	cout << endl;
	cout << endl;
	return 0;
}